import java.util.Random;

public final class GreedyRandomize2 extends Ejercicio
{ 
	public int[] Vo1, Vo2;
	public int cruces;
	
	protected Resultado DGIB
	(
			int n1, int v1[], int n2, int v2[], int m, Eje v1v2[],
			int np1, int vp1[], int np2, int vp2[], int mp, Eje vp1vp2[]
	){
		/*Constructiva aleatoria basada en constructiva*/
		
		Resultado res = new Resultado();
		
		int i; 
		int N1 = n1 + np1;
		int N2 = n2 + np2;
		int M = m + mp;
		
		Randomizar(vp1,np1);
		Randomizar(vp2,np2);
		
		Nodo[] IV1 = new Nodo[N1], IV2 = new Nodo[N2];
		Eje[] IV1V2 = new Eje[M];
		
		//7 declaraciones-asignaciones
		//1 declaracion
		//3 operaciones basicas
		//2 llamadas a funciones
		addPasos(13);
		
		for( i = 0; i < n1; i++ )
			IV1[i] = new Nodo(v1[i],false);
		
		for( i = 0; i < np1; i++ )
			IV1[n1+i] = new Nodo(vp1[i],true);
		
		for( i = 0; i < n2; i++ )
			IV2[i] = new Nodo(v2[i],false);
		
		for( i = 0; i < np2; i++ )
			IV2[n2+i] = new Nodo(vp2[i],true);
		
		for( i = 0; i < m; i++ )
			IV1V2[i] = v1v2[i];
		
		for( i = 0; i < mp; i++ )
			IV1V2[m+i] = vp1vp2[i];
		
		//n1 comparaciones
		//n1 operaciones basicas
		//n1 declaraciones-asignaciones
		//np1 comparaciones
		//np1*2 operaciones basicas
		//np1 declaraciones-asignaciones
		//n2 comparaciones
		//n2 operaciones basicas
		//n2 declaraciones-asignaciones
		//np2 comparaciones
		//np2*2 operaciones basicas
		//np2 declaraciones-asignaciones
		//m comparaciones
		//m operaciones basicas
		//m declaraciones-asignaciones
		//mp comparaciones
		//mp*2 operaciones basicas
		//mp comparaciones
		//mp declaraciones-asignaciones
		addPasos( n1*3+np1*4+n2*3+np2*4+m*3+mp*4 );
		
		//cruce maximo de ejes
		this.cruces = M*(M-1);
		//solucion optima
		this.Vo1 = new int[N1];
		this.Vo2 = new int[N2];
		
		Hconstructiva constructiva = new Hconstructiva();
		constructiva.DGIB(n1, v1, n2, v2, m, v1v2, np1, vp1, np2, vp2, mp, vp1vp2);
		
		//1 asignacion
		//3 declaraciones-asignaciones
		//2 operaciones basicas
		//1 llamado a funcion
		//pasos de constructiva
		addPasos( 7 + constructiva.getPasos() );
		
		cruces = constructiva.cruces;
		
		for( int l = 0; l < N1; l++ )
			this.Vo1[l] = constructiva.Vo1[l];
		
		for(int l = 0; l < N2; l++ )
			this.Vo2[l] = constructiva.Vo2[l];
		
		res.kid = cruces;
		res.n_iv1 = N1;
		res.iv1 = Vo1; 
		res.n_iv2 = N2;
		res.iv2 = Vo2;
		
		//N1 veces:
			//1 comparacion
			//1 operacion basica
			//1 asignacion
		//N2 veces:
			//1 comparacion
			//1 operacion basica
			//1 asignacion
		//2 comparaciones
		//7 asignaciones
		addPasos((N1+N2)*3+9);
		
		return res;
	}
	
	public void Randomizar(int[] V, int n)
	{
		Random cantMov = new Random();
		Random ind = new Random();
		Random ind2 = new Random();
		
		//3 declaraciones-asignaciones
		addPasos(3);
		
		for(int h = 0; h < cantMov.nextInt(n)+1;h++)
		{
			int i, j;
			i = ind.nextInt(n);
			j = ind2.nextInt(n);
			swap(V,i,j);
			
			//2 declaraciones
			//2 asignaciones
			//3 llamadas a funciones
			//1 comparacion
			//2 operaciones basicas
			addPasos(10);
		}
		
		//antes del ciclo:
			//1 declaracion-asignacion
		//despues del ciclo:
			//1 comparacion
		addPasos(2);
	}
} 
